/**
 * Hook-Fetch Plugins
 * 
 * Custom plugins for hook-fetch wrapper that provide authentication,
 * error handling, and request deduplication functionality.
 */

import type { HookFetchPlugin } from 'hook-fetch';
import type { 
  IHttpResponse, 
  AuthPluginConfig,
  ErrorHandlingPluginConfig,
  DeduplicationPluginConfig,
  RequestConfig,
  IObject
} from '../types/hookFetchTypes';
import { 
  STANDARD_HEADERS, 
  CONTENT_TYPES,
  DEFAULT_HTTP_ERROR_MESSAGES 
} from '../types/hookFetchTypes';
import { useUserStore } from '@/stores';

/**
 * Authentication Plugin Factory
 * 
 * Creates a plugin that automatically handles authentication headers,
 * locale headers, and request preprocessing for the hook-fetch wrapper.
 * 
 * Features:
 * - Automatic token injection from user store
 * - X-Requested-With header for AJAX identification
 * - Accept-Language header for internationalization
 * - Timestamp parameter for GET requests to prevent caching
 * - Form data serialization for application/x-www-form-urlencoded requests
 */
export function createAuthPlugin(config?: AuthPluginConfig): HookFetchPlugin<IHttpResponse> {
  const userStore = useUserStore();
  
  // Default configuration
  const pluginConfig: Required<AuthPluginConfig> = {
    getToken: () => userStore.token || null,
    getLocale: () => 'zh-CN', // Default to Chinese locale
    addTimestamp: true,
    ...config
  };

  return {
    name: 'authentication',
    beforeRequest: async (requestConfig) => {
      // Ensure headers exist and are mutable
      if (!requestConfig.headers) {
        requestConfig.headers = new Headers();
      } else if (!(requestConfig.headers instanceof Headers)) {
        requestConfig.headers = new Headers(requestConfig.headers);
      }

      // Add authentication token if available
      const token = pluginConfig.getToken();
      if (token) {
        requestConfig.headers.set(STANDARD_HEADERS.AUTHORIZATION, `Bearer ${token}`);
      }

      // Add X-Requested-With header for AJAX identification
      requestConfig.headers.set(STANDARD_HEADERS.X_REQUESTED_WITH, 'XMLHttpRequest');

      // Add Accept-Language header for internationalization
      const locale = pluginConfig.getLocale();
      if (locale) {
        requestConfig.headers.set(STANDARD_HEADERS.ACCEPT_LANGUAGE, locale);
      }

      // Handle GET requests - add timestamp parameter to prevent caching
      if (requestConfig.method === 'GET' && pluginConfig.addTimestamp) {
        // Ensure params object exists
        if (!requestConfig.params) {
          requestConfig.params = {};
        }
        
        // Add timestamp parameter
        requestConfig.params._t = Date.now().toString();
      }

      // Handle form data serialization for application/x-www-form-urlencoded
      const contentType = requestConfig.headers.get(STANDARD_HEADERS.CONTENT_TYPE);
      if (contentType === CONTENT_TYPES.FORM_URLENCODED && requestConfig.body) {
        // Convert body object to URLSearchParams for proper form encoding
        if (typeof requestConfig.body === 'object' && requestConfig.body !== null) {
          const formData = new URLSearchParams();
          
          // Serialize object to form data
          Object.entries(requestConfig.body as IObject).forEach(([key, value]) => {
            if (value !== null && value !== undefined) {
              formData.append(key, String(value));
            }
          });
          
          // Replace body with serialized form data
          requestConfig.body = formData.toString();
        }
      }

      return requestConfig;
    }
  };
}

/**
 * Error Handling Plugin Factory (placeholder for future implementation)
 * 
 * This will be implemented in task 4 - Create error handling plugin
 */
export function createErrorHandlingPlugin(config?: ErrorHandlingPluginConfig): HookFetchPlugin<IHttpResponse> {
  return {
    name: 'errorHandling',
    afterResponse: async (response) => {
      // Placeholder - will be implemented in task 4
      return response;
    },
    onError: async (error) => {
      // Placeholder - will be implemented in task 4
      return Promise.reject(error);
    }
  };
}

/**
 * Request Deduplication Plugin Factory (placeholder for future implementation)
 * 
 * This will be implemented in task 5 - Create request deduplication plugin
 */
export function createDeduplicationPlugin(config?: DeduplicationPluginConfig): HookFetchPlugin<IHttpResponse> {
  return {
    name: 'deduplication',
    beforeRequest: async (requestConfig) => {
      // Placeholder - will be implemented in task 5
      return requestConfig;
    },
    afterResponse: async (response) => {
      // Placeholder - will be implemented in task 5
      return response;
    }
  };
}